package webport_ss1

import (
	"context"
	"errors"
	"log"
	"net"

	"github.com/things-go/go-socks5"
	"wiseverds.com/frame/webport/src/service/webport_sp1"
)

var ListenAddr = "127.0.0.1:12521"

type Server struct {
	name   string
	server *socks5.Server
	Proxy  *webport_sp1.Proxy
}

func NewServer(proxy *webport_sp1.Proxy) *Server {

	return &Server{
		name:   "ss1",
		server: nil,
		Proxy:  proxy,
	}
}

func (s *Server) Start() {
	// Create a SOCKS5 server
	s.server = socks5.NewServer(
		socks5.WithResolver(MyDNSResolver{}),
		socks5.WithDial(func(ctx context.Context, net_, addr string) (net.Conn, error) {
			return s.dial(net_, addr)
		}),
	)

	go s.serve()
}

func (s *Server) Stop() {
}

func (s *Server) serve() {
	// Create SOCKS5 proxy
	if err := s.server.ListenAndServe("tcp", ListenAddr); err != nil {
		panic(err)
	}
}

// default: net.Dial(net_, addr)
func (s *Server) dial(net_, addr string) (net.Conn, error) {
	log.Println("webport_ss1: dial:", net_, addr)
	return s.Proxy.Dial(addr)
}

// MyDNSResolver uses the system DNS to resolve host names
type MyDNSResolver struct{}

// Resolve implement interface NameResolver
func (d MyDNSResolver) Resolve(ctx context.Context, name string) (context.Context, net.IP, error) {
	log.Println("webport_ss1: resolve:", name)

	if name != "webport-server.wiseverds.com" {
		return ctx, nil, errors.New("invalid host")
	}

	ip := "127.0.0.1"
	addr := &net.IPAddr{IP: net.ParseIP(ip)}
	return ctx, addr.IP, nil
}
